﻿// Silver.Globe, version 0.11 for Silverlight 1.1 Alpha
// Copyright © Florian Krüsch (xaml-kru.com)
// xaml-kru.com/silverglobe
// This source is subject to the Microsoft Public License (Ms-PL).
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx.
// All other rights reserved.

using System;
using System.Windows.Controls;
using System.IO;
using System.Collections.Generic;
using System.Windows.Shapes;
using System.Windows.Input;
using System.Windows.Media;
using SilverGlobe.Data;
using SilverGlobe.Math3D;
using System.Windows;

namespace SilverGlobe
{
    /// <summary>
    /// EventArgs for location selection events.
    /// </summary>
    public sealed class LocationEventArgs : EventArgs
    {
        private Location _location;

        /// <summary>
        /// The selected location
        /// </summary>
        public Location Location
        {
            get { return _location; }
        }

        public LocationEventArgs(Location locationData)
        {
            _location = locationData;
        }
    }

    public sealed partial class LocationSelector : Canvas
    {
        #region Members

        private IDictionary<FrameworkElement, Location> _locationLookup;

        #endregion

        #region Events

        public event EventHandler<LocationEventArgs> LocationSelected;

        public event EventHandler<LocationEventArgs> LocationMouseOver;

        public event EventHandler<LocationEventArgs> LocationMouseOut;

        #endregion

        #region Constructor

        public LocationSelector()
        {
            InitializeComponent();
        }

        #endregion

        #region Methods

        /// <summary>
        /// Initialize the LocationSelector with a list of locations.
        /// </summary>
        public void SetLocations(IEnumerable<Location> locations)
        {
            _locationLookup = new Dictionary<FrameworkElement, Location>();

            Children.Clear();

            foreach (Location loc in locations)
            {
                Ellipse ellipse = new Ellipse
                {
                    Cursor = Cursors.Hand,
                    Fill = new SolidColorBrush(Colors.Orange),
                    Stroke = new SolidColorBrush(Colors.White),
                    StrokeThickness = 1,
                    Width = 16,
                    Height = 16
                };

                TransformGroup tg = new TransformGroup();
                tg.Children.Add(new TranslateTransform());
                tg.Children.Add(new TranslateTransform { X = -8, Y = -8 });

                ellipse.RenderTransform = tg;
                ellipse.MouseLeftButtonDown += Location_MouseDown;
                ellipse.MouseEnter += Location_MouseOver;
                ellipse.MouseLeave += Location_MouseOut;

                _locationLookup.Add(ellipse, loc);

                Children.Add(ellipse);
            }
        }

        /// <summary>
        /// Update the visual display of the location dots.
        /// </summary>
        /// <param name="globe"></param>
        public void Update(IPositionProvider globe)
        {
            foreach (Ellipse ellipse in Children)
            {
                Location loc = _locationLookup[ellipse];

                Point3D pos = globe.ProjectPosition(loc.Position);

                if (pos.Z < 0)
                {
                    ellipse.Visibility = Visibility.Collapsed;
                }
                else
                {
                    ellipse.Visibility = Visibility.Visible;

                    TransformGroup transforms = (TransformGroup)ellipse.RenderTransform;
                    TranslateTransform translation = (TranslateTransform)transforms.Children[0];

                    translation.X = pos.X;
                    translation.Y = pos.Y;
                }
            }
        }

        #endregion

        #region Event handlers

        private void Location_MouseDown(object sender, MouseEventArgs e)
        {
            Ellipse ellipse = (Ellipse)sender;
            Location location = _locationLookup[ellipse];

            EventHandler<LocationEventArgs> h = LocationSelected;
            if (h != null) h(this, new LocationEventArgs(location));
        }

        private void Location_MouseOver(object sender, MouseEventArgs e)
        {
            Ellipse ellipse = (Ellipse)sender;
            Location location = _locationLookup[ellipse];

            EventHandler<LocationEventArgs> h = LocationMouseOver;
            if (h != null) h(this, new LocationEventArgs(location));
        }

        private void Location_MouseOut(object sender, EventArgs e)
        {
            Ellipse ellipse = (Ellipse)sender;
            Location location = _locationLookup[ellipse];

            EventHandler<LocationEventArgs> h = LocationMouseOut;
            if (h != null) h(this, new LocationEventArgs(location));
        }

        #endregion

    }
}
